package heap;

import java.util.*;
import java.util.stream.Collector;

/**
 * 查找和最小的 K 对数字
 */
public class SumSmallestKNumber {
    private class Pair {
        int a;
        int b;

        Pair(int a, int b) {
            this.a = a;
            this.b = b;
        }

        int sum() {
            return this.a + this.b;
        }
    }
    public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        // 最大堆
        Queue<Pair> queue = new PriorityQueue<>(new Comparator<Pair>() {
            @Override
            public int compare(Pair o1, Pair o2) {
                return (o2.a + o2.b) - (o1.a + o1.b);
            }
        });
        // 由于两个数组都是升序，所以取最小和最多只用遍历每个数组的 前k个和数组长度 中较小者个即可
        for (int i = 0; i < Math.min(nums1.length, k); i++) {
            for (int j = 0; j < Math.min(nums2.length, k); j++) {
                if (queue.size() < k) {
                    queue.offer(new Pair(nums1[i], nums1[j]));
                } else {
                    int sum = nums1[i] + nums1[j];
                    if (sum < queue.peek().sum()) {
                        Pair pair = new Pair(nums1[i], nums1[j]);
                        queue.poll();
                        queue.offer(pair);
                    }
                }
            }
        }
        List<List<Integer>> ret = new ArrayList<>();
        while (!queue.isEmpty() && ret.size() <= k) {
            List<Integer> list = new ArrayList<>();
            Pair pair = queue.poll();
            list.add(pair.a);
            list.add(pair.b);
            ret.add(list);
        }
        return ret;
    }
}
